<?php
namespace app\front\controller;

use app\BaseController;
use app\common\model\MbtiAnswers;
use app\common\model\MbtiNews;
use app\common\model\MbtiOrder;
use app\common\model\MbtiQuestions;
use app\common\model\MbtiTests;
use app\lib\pay\AliPay;
use app\lib\pay\wxPay;
use app\lib\Pdf;
use app\lib\qrcode\Qrcode;
use think\App;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\facade\Log;
use think\helper\Arr;
use think\response\Json;
use think\response\Redirect;
use think\View;
use think\facade\Cache;

class Index extends Base
{

    /**
     * 首页
     * @return \think\response\View
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function index()
    {
        $bzb = config('mbti.bzb');
        $zyb = config('mbti.zyb');
        $wzb = config('mbti.wzb');
        //获取图文资讯
        $news = MbtiNews::where('is_img',1)->order('id','desc')->limit(20)->select();
        foreach ($news as $v){
            $v['img'] = get_img_src($v['content']);
        }
        return view('./pc/index', ['bzb' => $bzb, 'zyb' => $zyb, 'wzb' => $wzb,'news'=>$news]);
    }

     /**
     * 获取题目
     * @return Json|Redirect
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getQuestion()
    {
        //检测来源是否正常
        $key = input('key');
        if (!in_array($key, ['bzb', 'zyb', 'wzb'])) {
            return redirect('/');
        }

        //查询题目
        $question = MbtiQuestions::where('category', $this->getKeyAttr[$key])
            ->select();
        $i = 0;
        foreach ($question as $item) {
            $item['station_id'] = $item['id'];
            $item['id'] = $i++;
//            echo $item['id']."\n";
//            MbtiQuestions::where('id', $item['station_id'])->update(['key' => $item['id']]);
        }

        $newArray = [];
        foreach ($question as $item) {
            $newArray[] = [
                'id' => $item['id'],
                'station_id' => $item['station_id'],
                'text' => $item['question'],
                'options' => [$item['option_a'], $item['option_b']]
            ];
        }
        return toJson(0, 'ok', $newArray);
    }
    
    /**
     * 答题页面
     * @return Redirect|\think\response\View
     */
    public function question()
    {
        //检测来源是否正常
        $key = input('key');
        if (!in_array($key, ['bzb', 'zyb', 'wzb'])) {
            return redirect('/');
        }
        $info = config("mbti.$key");
        return view('./pc/question', ['info' => $info]);
    }

    /**
     * 生成报告
     * @return Json|Redirect|\think\response\View
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function report()
    {
          if (request()->isPost()) {
            $data = input('post.');
            if (empty($data['key'])) {
                return toJson(1, "提交参数不合法", null);
            }
            if (empty($data['option'])) {
                return toJson(1, "提交参数不合法", null);
            }
            //检测题目数量
            $option = $data['option'];

            if ($this->queryMbtiQuestion($data['key']) != count($option)) {
                 return toJson(1, "提交参数不合法", null);
            }
            Db::startTrans();
            try {
                $orderNo = date('Y') . rand(100000, 999999);
                $password = rand(10000000, 99999999);
                //写入用户答题数量
                $this->addAAnswer($data, $option, $orderNo);
                $myAnswers = MbtiAnswers::where('test_type', $this->getKeyAttr[$data['key']])
                    ->where('order_no', $orderNo)
                    ->select()
                    ->toArray();
                //计算实际分
                calculateDimensionScores($myAnswers, $orderNo, $this->getKeyAttr[$data['key']], $password);
                //加密密码
                $sha256Hash = hash('sha256',  $password);
                MbtiTests::where('order_no', $sha256Hash)
                    ->update(['secret' => $sha256Hash, 'secret_time' => time() + 300]);
                Db::commit();
            } catch (\Exception $e) {
                Log::info('report----------------------' . date('Y-m-d') . json_encode($e->getMessage() . '--' . $e->getFile() . '--' . $e->getLine()));
                Db::rollback();
                // print_r($e->getMessage() . '--' . $e->getFile() . '--' . $e->getLine());die;
                return toJson(1, '提交失败', null);

            }
            (new Pdf())->createPdf(['url' => request()->domain() . '/report?order_no=' . $orderNo . "&secret=" . $password . '&channel=system', 'filename' => $orderNo . '.pdf']);

            return toJson(0, '提交成功', ['order_no' => $orderNo]);
        }

        $order_no = input('order_no');
        $secret = input('secret', "");
        $channel = input('channel','user');
        if (empty($order_no)) {
            return redirect('/');
        }
        //查询订单
        $order = MbtiTests::where('order_no', $order_no)->find();
        if (empty($order)) {
            return $this->error();
        }
        $isAuth = $channel == "system" || !empty(session('user_id')) || $order['version'] =='免费版' ? 0 :1;
        if($isAuth) {
            if ($secret != $order['secret']) {
                return $this->error();
            }
            //检测密钥是否过期
            if (time() >= $order['secret_time']) {
                return $this->error();
            }
        }
        if (empty($order)) {
            return $this->error();
        }

        $data = file_get_contents("./mb.json");
        $datas = json_decode($data, true)['mbti_types'];
        $datas = Arr::pluck($datas, [], 'type_code');
        $detail = $datas[$order['result_type']];
        $text = json_decode($order['text'], true);
        $detail['a'] = $text[0]['E'] >= $text[0]['I'] ? bcadd($text[0]['E'], 0, 0) : bcadd($text[0]['I'], 0, 0);
        $detail['b'] = $text[1]['S'] >= $text[1]['N'] ? bcadd($text[1]['S'], 0, 0) : bcadd($text[1]['N'], 0, 0);
        $detail['c'] = $text[2]['T'] >= $text[2]['F'] ? bcadd($text[2]['T'], 0, 0) : bcadd($text[2]['F'], 0, 0);
        $detail['d'] = $text[3]['J'] >= $text[3]['P'] ? bcadd($text[3]['J'], 0, 0) : bcadd($text[3]['P'], 0, 0);
        $mbtiBias = config('mbti.mbtiBias');
        $detail['a_text'] = $text[0]['E'] >= $text[0]['E'] ? $mbtiBias['e'] : $mbtiBias['i'];
        $detail['b_text'] = $text[1]['S'] >= $text[1]['N'] ? $mbtiBias['s'] : $mbtiBias['n'];
        $detail['c_text'] = $text[2]['T'] >= $text[2]['F'] ? $mbtiBias['t'] : $mbtiBias['f'];
        $detail['d_text'] = $text[3]['J'] >= $text[3]['P'] ? $mbtiBias['j'] : $mbtiBias['p'];

        $task = (new Pdf)->getTask($order_no.'.pdf');
        //检测任务
        if(!empty($task['status']) && in_array($task['status'], ['failed','error'])) {
            if (empty($order['secret'])) {
                //重新生成密钥
                $order['secret'] = hash('sha256', $order['password'] . rand(10000000, 99999999));
                MbtiTests::where('order_no', $order['order_no'])
                    ->update(['secret' => $order['secret'], 'secret_time' => time() + 300]);
            }
            //生成pdf
            (new Pdf())->createPdf(['url' => request()->domain() . '/report?order_no=' . $order['order_no'] . "&secret=" . $order['secret'] . '&channel=system', 'filename' => $order['order_no'] . '.pdf']);

        }
        return view('./pc/report', ['order' => $order, 'detail' => $detail,'channel' => $channel]);
    }

    /**
     * 查询题目列表
     * @param $key
     * @param $questionId
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function queryQueStationList($key, $questionId)
    {
        $que = MbtiQuestions::where('category', $this->getKeyAttr[$key])
            ->whereIn('key', $questionId)
            ->select()
            ->toArray();
        return $que;
    }

    /**
     * 查询题目总数
     * @param $key
     * @return int
     * @throws DbException
     */
    public function queryMbtiQuestion($key)
    {
        return MbtiQuestions::where('category', $this->getKeyAttr[$key])
            ->count();
    }

    /**
     * 文章详情
     * @return \think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function newsDetail()
    {
        $id = input('id');
        $detail = MbtiNews::where('id', $id)->find();
        if (empty($detail)) {
            return $this->error();
        }
        MbtiNews::where('id', $id)
            ->update(['pv' => $detail['pv'] + 1]);
        //获取最新浏览的
        $pv = MbtiNews::order('pv', 'desc')->limit(5)->select();
        $order = MbtiNews::order('id', 'desc')->limit(15)->select();
        return view('./pc/news_detail', ['pv' => $pv, 'order' => $order, 'detail' => $detail]);
    }

    /**
     * 添加答题
     * @param $data
     * @param $option
     * @param $orderNo
     * @return array|MbtiQuestions[]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function addAAnswer($data, $option, $orderNo)
    {
        //题目id
        $questionId = array_keys($data['option']);
        //查询题目
        $question = $this->queryQueStationList($data['key'], $questionId);
        $questionId = array_column($question, 'id', 'key');
        $dimension = array_column($question, 'dimension', 'key');
        foreach ($option as $k => $v) {
            $answer['order_no'] = $orderNo;
            $answer['question_id'] = $questionId[$k];       //题目id
            $answer['test_type'] = $this->getKeyAttr[$data['key']];
            $answer['answer'] = $v == 0 ? 'A' : "B";
            $answer['dimension'] = $dimension[$k];
            MbtiAnswers::insert($answer);
        }
        return $question;
    }

    /**
     * 报告授权页
     * @return Json|Redirect|\think\response\View
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function result()
    {
        if ($this->request->isPost()) {
            $data = input('post.');
            if (!$data['order_no']) {
                return toJson(1, '请输入订单号');
            }
            //查询支付订单
            $res = MbtiOrder::where('order_no', $data['order_no'])
                ->find();
            if (!$res) {
                return toJson(1, '输入的商户订单不存在');
            }
            //查询报告订单
            $res = MbtiTests::where('order_no', $res['business_order_no'])
                ->find();
            if (!$res) {
                return toJson(1, '报告被删除,请联系客服');
            }
            //加密密码
            $sha256Hash = hash('sha256', rand(10000000, 99999999));
            MbtiTests::where('order_no', $res['order_no'])
                ->update(['secret' => $sha256Hash, 'secret_time' => time() + 300]);
            //投递任务
        
            $pdf = (new Pdf())->createPdf([
                'url' => request()->domain() . '/report?order_no=' . $res['order_no'] . "&secret=" . $sha256Hash.'&channel=system',
                'filename' => $res['order_no'] . '.pdf']
            );
            if (!empty($pdf['status']) && $pdf['status'] == 'error'){
                return toJson(1, $pdf['error']);
            }
            return toJson(0, 'ok', ['password' => $sha256Hash, 'order_no' => $res['order_no']]);
        }
        $orderNo = input('order_no');
        if (empty($orderNo)) {
            return $this->error();
        }
        $order = MbtiTests::where('order_no', $orderNo)->find();
        if (empty($order)) {
            return $this->error();
        }
        $minutes = 15;
        if (empty($order['close_time'])){
            $newTimestamp = strtotime("+$minutes minutes", time());
            MbtiTests::where('order_no', $orderNo)->update(['close_time' => date('Y-m-d H:i:s',$newTimestamp)]);
            $order = MbtiTests::where('order_no', $orderNo)->find();
        }
        if ($order['version'] == "免费版"){
            return \redirect('/report?order_no=' . $orderNo);
        }
        $orderCheck = MbtiOrder::where('business_order_no', $order['order_no'])->find();
        if (!empty($orderCheck) && $orderCheck['is_pay'] == 1){
            return \redirect('/');
        }

        $price = $this->conf[$this->getArrKey[$order['version']]];
        return \view('./pc/results', ['order_no' => $orderNo,'price' =>$price,'key' => $this->getArrKey[$order['version']]]);
    }
}